home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Applications / QuArK / quarkpy / mdlutils.py < prev    next >
Text File  |  2004-01-05  |  7KB  |  287 lines

  1. """   QuArK  -  Quake Army Knife
  2.  
  3. Various Model editor utilities.
  4. """
  5. #
  6. # Copyright (C) 1996-99 Armin Rigo
  7. # THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
  8. # FOUND IN FILE "COPYING.TXT"
  9. #
  10.  
  11. #$Header: /cvsroot/quark/runtime/quarkpy/mdlutils.py,v 1.7 2001/03/15 21:07:49 aiv Exp $
  12.  
  13.  
  14.  
  15. import quarkx
  16. from qeditor import *
  17. from math import *
  18.  
  19. #
  20. # Calculate Position of a Point along the vector AC, Keeping L (Length)
  21. #
  22. def ProjectKeepingLength(A,C,L):
  23.   def NormaliseVect(v1, v2):
  24.     le = sqrt( pow(v2.x - v1.x, 2) + 
  25.                pow(v2.y - v1.y, 2) +  
  26.                pow(v2.z - v1.z, 2) )
  27.     if (le <> 0): 
  28.       v = quarkx.vect( \
  29.         (v2.x - v1.x) / le, \
  30.         (v2.y - v1.y) / le, \
  31.         (v2.z - v1.z) / le  )
  32.     else:
  33.       v = quarkx.vect(0,0,0)
  34.     return v
  35.   n = NormaliseVect(A, C)
  36.   xxx = quarkx.vect(
  37.     A.x + (L * n.x),
  38.     A.y + (L * n.y),
  39.     A.z + (L * n.z)
  40.     )
  41.   return xxx
  42.  
  43. #
  44. # Invalidate all views
  45. #
  46. def invalidateviews():
  47.   editor = mapeditor()
  48.   if editor is None: return
  49.   editor.invalidateviews(1)
  50.  
  51.  
  52. #
  53. #  Find a triangle based on vertex indexs
  54. #
  55. def findTriangle(comp, v1, v2, v3):
  56.   tris = comp.triangles
  57.   index = -1
  58.   for tri in tris:
  59.     index = index + 1
  60.     b = 0
  61.     for c in tri:
  62.       if ((c[0] == v1) | (c[0] == v2) | (c[0] == v3)):
  63.         b = b + 1
  64.       else:
  65.         b = 0
  66.     if b==3:
  67.       return index
  68.   return None
  69.       
  70.  
  71. #
  72. # Remove a triangle from a given component
  73. #
  74. def removeTriangle_v3(comp, v1, v2, v3):
  75.   removeTriangle(comp, findTriangle(comp, v1,v2,v3))
  76.   
  77.   
  78. #
  79. # Remove a triangle from a given component
  80. #
  81. def removeTriangle(comp, index):
  82.   if (index is None):
  83.     return
  84.   new_comp = comp.copy()
  85.   old_tris = new_comp.triangles
  86.   tris = old_tris[:index] + old_tris[index+1:]
  87.   new_comp.triangles = tris
  88.   undo = quarkx.action()
  89.   undo.exchange(comp, new_comp)
  90.   mapeditor().ok(undo, "remove triangle")
  91.   invalidateviews()
  92.     
  93.  
  94. #
  95. # Add a frame to a given component (ie duplicate last one)
  96. #
  97. def addframe(comp):
  98.   if (comp is None):
  99.     return
  100.   new_comp = comp.copy()
  101.   f = new_comp.addframe() # easier - done in delphi code :-)
  102.   f.refreshtv()
  103.   undo = quarkx.action()
  104.   undo.exchange(comp, new_comp)
  105.   mapeditor().ok(undo, "add frame")
  106.   
  107.   invalidateviews()
  108.   return f
  109.  
  110. #
  111. # Add a triangle to a given component
  112. #
  113. def addtriangle(comp,v1,v2,v3,s1,t1,s2,t2,s3,t3):
  114.   if (comp is None) or (v1 is None) or (v2 is None) or (v3 is None):
  115.     return
  116.   if (s1 is None) or (s2 is None) or (s3 is None):
  117.     return
  118.   if (t1 is None) or (t2 is None) or (t3 is None):
  119.     return
  120.   tris = comp.triangles
  121.   tris = tris + [((v1,s1,t1),(v2,s2,t2),(v3,s3,t3))]
  122.   new_comp = comp.copy()
  123.   new_comp.triangles = tris
  124.  
  125.   undo = quarkx.action()
  126.   undo.exchange(comp, new_comp)
  127.   mapeditor().ok(undo, "add triangle")
  128.   invalidateviews()
  129.  
  130. #
  131. # Add a vertex to a given component at origin specified
  132. #
  133. def addvertex(comp, org):
  134.   if (comp is None) or (org is None):
  135.     return
  136.   new_comp = comp.copy()
  137.   frames = new_comp.findallsubitems("", ':mf')   # find all frames
  138.   for frame in frames: 
  139.     vtxs = frame.vertices
  140.     vtxs = vtxs + [org]
  141.     frame.vertices = vtxs
  142.  
  143.   undo = quarkx.action()
  144.   undo.exchange(comp, new_comp)
  145.   mapeditor().ok(undo, "add vertex")
  146.  
  147.   invalidateviews()
  148.   
  149. #
  150. # Checks triangle for vertex [index]
  151. #
  152. def checkTriangle(tri, index):
  153.   for c in tri:
  154.     if ( c[0] == index): # c[0] is the 'vertexno'
  155.       return 1  
  156.   return 0
  157.  
  158.  
  159. #
  160. # Find triangles containing a selected vertex  [index]
  161. #
  162. def findTriangles(comp, index):
  163.   tris = comp.triangles
  164.   tris_out = [ ]
  165.   for tri in tris:
  166.     isit = checkTriangle(tri, index)
  167.     if (isit == 1):
  168.       tris_out = tris_out + [ tri ]
  169.   return tris_out
  170.  
  171. def fixTri(tri, index):
  172.   new_tri = [ ]
  173.   for c in tri:
  174.     v = 0
  175.     if ( c[0] > index):
  176.       v = c[0]-1
  177.     else:
  178.       v = c[0]
  179.     s = c[1]
  180.     t = c[2]
  181.     new_tri = new_tri + [(v,s,t)]
  182.   return (new_tri[0], new_tri[1], new_tri[2])
  183.   
  184. #
  185. # goes through tri list: if greaterthan index then takes 1 away from vertexno
  186. #
  187. def fixUpVertexNos(tris, index):
  188.   new_tris = [ ]
  189.   for tri in tris:
  190.      x = fixTri(tri, index)
  191.      new_tris = new_tris + [x]
  192.   return new_tris
  193.  
  194. def checkinlist(tri, toberemoved):
  195.   for tbr in toberemoved:
  196.     if (tri == tbr):
  197.       return 1
  198.   return 0
  199.  
  200. #
  201. # remove a vertex from a component
  202. #
  203. def removevertex(comp, index):
  204.   if (comp is None) or (index is None):
  205.     return
  206.   #### 1) find all triangles that use vertex 'index' and delete them.
  207.   toBeRemoved = findTriangles(comp, index)
  208.   tris = comp.triangles
  209.   new_tris = []
  210.   for tri in tris:
  211.     p = checkinlist(tri, toBeRemoved)
  212.     if (p==0):
  213.       new_tris = new_tris + [ tri ]
  214.   enew_tris = fixUpVertexNos(new_tris, index)
  215.   new_comp = comp.copy() # create a copy to edit (we store the old one in the undo list)
  216.   new_comp.triangles = enew_tris
  217.   #### 2) loop through all frames and delete vertex.
  218.   frames = new_comp.findallsubitems("", ':mf')   # find all frames
  219.   for frame in frames: 
  220.     old_vtxs = frame.vertices
  221.     vtxs = old_vtxs[:index] + old_vtxs[index+1:]
  222.     frame.vertices = vtxs
  223.   #### 3) re-build all views
  224.   undo = quarkx.action()
  225.   undo.exchange(comp, new_comp)
  226.   mapeditor().ok(undo, "remove vertex")
  227.   invalidateviews()
  228.  
  229. #
  230. # Is a given object still in the tree view, or was it removed ?
  231. #
  232. def checktree(root, obj):
  233.     while obj is not root:
  234.         t = obj.parent
  235.         if t is None or not (obj in t.subitems):
  236.             return 0
  237.         obj = t
  238.     return 1     
  239.  
  240.  
  241. #
  242. # The UserDataPanel class, overridden to be model-specific.
  243. #
  244.  
  245. class MdlUserDataPanel(UserDataPanel):
  246.  
  247.     def btnclick(self, btn):
  248.         #
  249.         # Send the click message to the module mdlbtns.
  250.         #
  251.         import mdlbtns
  252.         mdlbtns.mdlbuttonclick(btn)
  253.  
  254.     #def drop(self, btnpanel, list, i, source):
  255.         #if len(list)==1 and list[0].type == ':g':
  256.         #    quarkx.clickform = btnpanel.owner
  257.         #    editor = mapeditor()
  258.         #    if editor is not None and source is editor.layout.explorer:
  259.         #        choice = quarkx.msgbox("You are about to create a new button from this group. Do you want the button to display a menu with the items in this group ?\n\nYES: you can pick up individual items when you click on this button.\nNO: you can insert the whole group in your map by clicking on this button.",
  260.         #          MT_CONFIRMATION, MB_YES_NO_CANCEL)
  261.         #        if choice == MR_CANCEL:
  262.         #            return
  263.         #        if choice == MR_YES:
  264.         #            list = [group2folder(list[0])]
  265.         #UserDataPanel.drop(self, btnpanel, list, i, source)
  266.  
  267. # ----------- REVISION HISTORY ------------
  268. #
  269. #
  270. #$Log: mdlutils.py,v $
  271. #Revision 1.7  2001/03/15 21:07:49  aiv
  272. #fixed bugs found by fpbrowser
  273. #
  274. #Revision 1.6  2001/02/01 22:03:15  aiv
  275. #RemoveVertex Code now in Python
  276. #
  277. #Revision 1.5  2000/10/11 19:07:47  aiv
  278. #Bones, and some kinda skin vertice viewer
  279. #
  280. #Revision 1.4  2000/08/21 21:33:04  aiv
  281. #Misc. Changes / bugfixes
  282. #
  283. #Revision 1.2  2000/06/02 16:00:22  alexander
  284. #added cvs headers
  285. #
  286. #
  287. #